﻿package framework.core;

import java.math.BigDecimal;


/**
 * Creation date: (2003-08-28)
 * @author: adminnistrator
 * 值包装类
 * 支持 int,double,String,java.sql.Date,DateUtil数据类型
 */

public class Value 
{
	
	public static final int TYPE_INT       = 1;
	public static final int TYPE_DOUBLE    = 2;
	public static final int TYPE_STRING    = 3;
	public static final int TYPE_DATE_UTIL = 4;
	public static final int TYPE_BYTES     = 5; //二进制数据
	public static final int TYPE_DATE      = 6; //日期型

    public static final int      NULL_INT = -1357904680;
	public static final double  NULL_DOUBLE = -1357904680;
	
	private int m_type;
	
	private int    m_value_int ;
	private double m_value_double;
	private String m_value_string;
	private DateUtil m_value_date_util ;
	private byte[] m_value_bytes ;

	public Value(int v)
	{
		setValue(v);
	}
	public Value(double v)
	{
		setValue(v);
	}
	public Value(String v)
	{
		setValue(v);
	}
	public Value(DateUtil v)
	{
		setValue(v);
	}
	public Value(byte[] v)
	{
		setValue(v);
	}
	
	public Value(Value v)
	{
		m_type = v.m_type;
		m_value_int = v.m_value_int;
		m_value_double = v.m_value_double;
		m_value_string = v.m_value_string;
		m_value_date_util = v.m_value_date_util;
		m_value_bytes = v.m_value_bytes;
	}
	
	public int getType()
	{
		return m_type;
	}
	private void setType(int v)
	{
		m_type = v;
	}
	public void setValue(int v)
	{
		m_type = TYPE_INT ;
		m_value_int = v ; 
	}
	public void setValue(double v)
	{
		m_type = TYPE_DOUBLE ;
		m_value_double = v ; 
	}
	public void setValue(String v)
	{
		m_type = TYPE_STRING ;
		m_value_string = v ; 
	}
	public void setValue(DateUtil v)
	{
		m_type = TYPE_DATE_UTIL;
		m_value_date_util = v ; 
	}
	public void setValue(byte[] v)
	{
		m_type = TYPE_BYTES;
		m_value_bytes = v ; 
	}
	public boolean isInt()
	{
		return m_type==TYPE_INT;
	}
	public boolean isDouble()
	{
		return m_type==TYPE_DOUBLE;
	}
	public boolean isString()
	{
		return m_type==TYPE_STRING;
	}
	public boolean isDateUtil()
	{
		return m_type==TYPE_DATE_UTIL;
	}
	public boolean isBytes()
	{
		return m_type==TYPE_BYTES;
	}
	public boolean isNull() throws Exception
	{
		if(isInt()) return getInt()==NULL_INT;
		if(isDouble()) return getDouble()==NULL_DOUBLE;
		if(isString()) return getString()==null;
		if(isDateUtil()) return getDateUtil()==null;
		if(isBytes()) return getBytes()==null;
		Logger.throwException(this,getClassName()+"[未知的数据类型]");
		return false;
	}
	public int getInt() throws Exception
	{
		if(!isInt())
		{
			Logger.throwException(this,getClassName()+".getInt():数据类型不正确,无法得到整数型值!");
		}
		return m_value_int;
	}
	public double getDouble() throws Exception
	{
		if(!isDouble())
		{
			Logger.throwException(this,getClassName()+".getInt():数据类型不正确,无法得到浮点数型值!");
		}
		return m_value_double;
	}
	public String getString() throws Exception
	{
		if(!isString())
		{
			Logger.throwException(this,getClassName()+".getInt():数据类型不正确,无法得到字符串型值!");			
		}
		return m_value_string ;
	}
	public DateUtil getDateUtil() throws Exception
	{
		if(!isDateUtil())
		{
			Logger.throwException(this,getClassName()+".getInt():数据类型不正确,无法得到日期型值!");	
		}
		return m_value_date_util ;
	}
	public byte[] getBytes() throws Exception
	{
		if(!isBytes())
		{
			Logger.throwException(this,getClassName()+".getBytes():数据类型不正确,无法得到二进制型值!");	
		}
		return m_value_bytes ;
	}
	
	public String toString()
	{
		try
		{
			if(isInt())
			{
				if(getInt()==NULL_INT)
				{
					return getClassName()+"[int=null]";
				}
				return getClassName()+"[int="+getInt()+"]";
			}
			else if(isDouble())
			{
				if(getDouble()==NULL_DOUBLE)
				{
					return getClassName()+"[double=null]";
				}
				return getClassName()+"[double="+getDouble()+"]";
			}
			else if(isString())
			{
				String v = getString();
				if(v==null)
				{
					return getClassName()+"[String=null]";
				}
				else
				{
					return getClassName()+"[String="+v+"]";
				}
				
			}
			else if(isDateUtil())
			{
				DateUtil d = getDateUtil();
				if(d==null)
				{
					return getClassName()+"[DateUtil=null]";
				}
				else
				{
					return getClassName()+"[DateUtil="+d.toString()+"]";
				}
			}
			else if(isBytes())
			{
				byte[] v = getBytes();
				if(v==null)
				{
					return getClassName()+"[null]";
				}
				else
				{
					return getClassName()+"[bytes]";
				}
			}
			else
			{
				return getClassName()+"[未知的数据类型]";
			}
		}
		catch(Exception e)
		{
			return getClassName()+"[发生异常:"+e.getMessage()+"]!";
		}
	}
	
	public boolean equals(int v) throws Exception
	{
		if(!isInt()) return false;
		return getInt()==v;
	}
	public boolean equals(double v) throws Exception
	{
		if(!isDouble()) return false;
		return getDouble()==v;
	}
	public boolean equals(String v) throws Exception
	{
		if(!isString()) return false;
		if(isNull()) return v==null;
		return getString().equals(v);
	}
	public boolean equals(DateUtil v) throws Exception
	{
		if(!isDateUtil()) return false;
		if(isNull()) return v==null;
		return getDateUtil().equals(v);
	}
	public boolean equals(byte[] v) throws Exception
	{
		if(!isBytes()) return false;
		if(isNull()) return v==null;
		return getBytes().equals(v);
	}
	public boolean equals(Value v) throws Exception
	{
		if(v.getType()==TYPE_INT) return equals(v.getInt());
		if(v.getType()==TYPE_DOUBLE) return equals(v.getDouble());
		if(v.getType()==TYPE_STRING) return equals(v.getString());
		if(v.getType()==TYPE_DATE_UTIL) return equals(v.getDateUtil());
		if(v.getType()==TYPE_BYTES) return equals(v.getBytes());
		Logger.throwException(this,getClassName()+"[未知的数据类型]");
		return false;
	}
	public boolean equals(Object obj)
	{
		try
		{
			if(obj instanceof Value)
			{
				return equals((Value)obj);
			}
			else if(obj instanceof Integer)
			{
				int v = ((Integer)obj).intValue();
				return equals(v);
			}
			else if(obj instanceof Double)
			{
				double v = ((Double)obj).doubleValue();
				return equals(v);
			}
			else if(obj instanceof String)
			{
				String v = (String) obj;
				return equals(v);
			}
			else if(obj instanceof DateUtil)
			{
				DateUtil v = (DateUtil) obj;
				return equals(v);
			}
			else if(obj instanceof byte[])
			{
				byte[] v = (byte[]) obj;
				return equals(v);
			}
			else
			{
				return false;
			}
		}
		catch(Exception e)
		{
			Logger.logException(this,e);
			return false;
		}
		
	}
	
	//转换数据类型
	//int     -> doube,String
	//double  -> int,String
	//String  -> int,double,Date,DateUtil
	//Date    -> String,DateUtil
	//DateUtil-> String,DateUtil
	public void toType(int type) throws Exception
	{
		if(getType()==type) return ;

		if(isInt())
		{
			if(type==TYPE_DOUBLE)
			{
				double v = isNull() ? NULL_DOUBLE : (double)getInt();
				setValue(v);
			}
			else if(type==TYPE_STRING)
			{
				String v = isNull() ? null : ""+getInt();
				setValue(v);
			}
			else
			{
				Logger.throwException(this,getClassName()+".toType(from:"+toString()+",to:"+type+"):无法进行数据类型的转换!");
			}
		}
		else if(isDouble())
		{
			if(type==TYPE_INT)
			{
				int v = isNull() ? NULL_INT : (int)getDouble();
				setValue(v);
			}
			else if(type==TYPE_STRING)
			{
				String v = isNull() ? null : ""+getDouble();
				setValue(v);
			}
			else
			{
				Logger.throwException(this,getClassName()+".toType(from:"+toString()+",to:"+type+"):无法进行数据类型的转换!");
			}
		}
		else if(isString())
		{
			String s = getString();
			if(type==TYPE_INT)
			{
				setValue(Integer.parseInt(s));
			}
			else if(type==TYPE_DOUBLE)
			{
				setValue(Double.parseDouble(s));
			}
			else if(type==TYPE_DATE_UTIL)
			{
				DateUtil d = new DateUtil(s);
				setValue(d);
			}
			else
			{
				Logger.throwException(this,getClassName()+".toType(from:"+toString()+",to:"+type+"):无法进行数据类型的转换!");
			}
		}
		else if(isDateUtil())
		{
			if(type==TYPE_STRING)
			{
				setValue(getDateUtil().toString());				
			}
			else
			{
				Logger.throwException(this,getClassName()+".toType(from:"+toString()+",to:"+type+"):无法进行数据类型的转换!");
			}
		}
		else
		{
			Logger.throwException(this,getClassName()+"[未知的数据类型]");
		}
			
	}
	
	public String viewString() throws Exception
	{
		if(isNull()) return "";
		
		if(isInt())
		{
			return ""+getInt();
		}
		else if(isDouble())
		{
			return ""+getDouble();
		}
		else if(isString())
		{
			return getString();
		}
		else if(isDateUtil())
		{
			return getDateUtil().toString();
		}
		else if(isBytes())
		{
			return "bytes[length="+getBytes().length+"]";
		}
		else
		{
			Logger.throwException(this,getClassName()+".viewString():未知的数据类型,无法显示值!");
			return "exception";
		}
	}
	
	public static String view(int v) 
	{
		if(v==NULL_INT) return "";
		return ""+v;
	}
	
	public static String view(double v) 
	{
		if(v==NULL_DOUBLE) return "";
		return ""+v;
	}
	
	
	public static String viewMoney(double v) 
	{
		return view(v,Config.getFormatMoney());
	}
	public static String viewInputMoney(double v) 
	{
		return view(v,Config.getFormatMoneyInput());
	}		
	public static String viewQty(double v) 
	{
		return view(v,Config.getFormatQty());
	}
	public static String viewInputQty(double v) 
	{
		return view(v,Config.getFormatQtyInput());
	}
	public static String viewPrice(double v) 
	{
		return view(v,Config.getFormatPrice());
	}
	public static String viewInputPrice(double v) 
	{
		return view(v,Config.getFormatPriceInput());
	}
	
	public static String viewOilQtyLiter(double v)
	{
		return view(v, Config.getFormatOilQtyLiter());
	}
	
	public static String viewOilQtyTon(double v)
	{
		return view(v, Config.getFormatOilQtyTon());
	}	
	
	public static String view(double v,String format) 
	{
		if(v==NULL_DOUBLE) return "";
		java.text.DecimalFormat fmt = new java.text.DecimalFormat(format);
		return fmt.format(v);
	}
	public static double format(double v,String format) 
	{
		java.text.DecimalFormat fmt = new java.text.DecimalFormat(format);
		return Double.parseDouble(fmt.format(v));
	}
		
	public static String view(String v) 
	{
		if(v==null||v.equalsIgnoreCase("")) return "";
		
		return v;
	}
	public static String view(byte[] v) 
	{
		if(v==null) return "-无-";
		return "二进制数据";
	}
	
	public static String viewPercent(double v)
	{
		if(v==NULL_DOUBLE) return "0.00%";
		
		return view(v*100, "####.##") + "%";
	}
	
	public static String viewPercentValue(double v)
	{
		if(v==NULL_DOUBLE) return "";
		double result = v*100;
		return view(result, "####");
	}
	
	public String getClassName()
	{
		return "";
		//return this.getClass().getName();
	}
	
	//parse functions
	public static int parseInt(String sValue,int defValue)
	{
		try
		{
			return Integer.parseInt(sValue);
		}
		catch(Exception e)
		{
			return defValue;
		}
	}
	
	public static double parseDouble(String sValue,double defValue)
	{
		try
		{
			return Double.parseDouble(sValue);
		}
		catch(Exception e)
		{
			return defValue;
		}
	}
	
//	中文金额单位数组
	  public static final String[] straChineseUnit =
		   new String[] {"分", "角", "圆", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟"};
	  //中文数字字符数组
	  public static final String[] straChineseNumber = 
		  new String[] {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};

	  /**
	  * Description 将数字金额转换为中文金额
	  * @param 
	
	  BigDecimal bigdMoneyNumber 转换前的数字金额
	  * @return String
	  调用：myToChineseCurrency("101.89")="壹佰零壹圆捌角玖分"
	  myToChineseCurrency("100.89")="壹佰零捌角玖分"
	  myToChineseCurrency("100")="壹佰圆整"
	  */
	  public static String doConvert(double money) 
	  {
		  BigDecimal bigdMoneyNumber = new BigDecimal(money);
		  String strChineseCurrency = "";
		  //零数位标记
		  boolean bZero = true;
		  //中文金额单位下标
		  int ChineseUnitIndex = 0;
		
//		  DoPrintMessage("Calling Method doConvert");
		
		  try 
		  {
			  if (bigdMoneyNumber.intValue() == 0)
				  return "零圆整";
		
			  //处理小数部分，四舍五入
			  double doubMoneyNumber = Math.round(bigdMoneyNumber.doubleValue() * 100);
			  //是否负数
			  boolean bNegative = doubMoneyNumber < 0;
		
			  //取绝对值
			  doubMoneyNumber = Math.abs(doubMoneyNumber);
		
			  //循环处理转换操作
			  while (doubMoneyNumber > 0) 
			  {
				  //整的处理(无小数位)
				  if (ChineseUnitIndex == 2 && strChineseCurrency.length() == 0)
					  strChineseCurrency = strChineseCurrency + "整";
		
				  //非零数位的处理
				  if (doubMoneyNumber % 10 > 0) 
				  {
					  strChineseCurrency = straChineseNumber[(int)(doubMoneyNumber % 10)] 
						  + straChineseUnit[ChineseUnitIndex] + strChineseCurrency;
					  bZero = false;
				  }
				  //零数位的处理
				  else
				  {
					  //元的处理(个位)
					  if (ChineseUnitIndex == 2 )
					  {
						  //段中有数字
						  if (doubMoneyNumber > 0) {
						  strChineseCurrency = straChineseUnit[ChineseUnitIndex] + 
											  strChineseCurrency;
						  bZero = true;
					  }
				  }
				  //万、亿数位的处理
				  else if (ChineseUnitIndex == 6 || ChineseUnitIndex == 10) 
				  {
					  //段中有数字
					  if (doubMoneyNumber % 1000 > 0)
						  strChineseCurrency = straChineseUnit[ChineseUnitIndex] + 
								  strChineseCurrency;
				  }
			
					  //前一数位非零的处理
					  if (!bZero)
						  strChineseCurrency = straChineseNumber[0] + 
							  strChineseCurrency;
			
					  bZero = true;
				  }
			
				  doubMoneyNumber = Math.floor(doubMoneyNumber / 10);
				  ChineseUnitIndex ++;
			  }
			
			  //负数的处理
			  if (bNegative)
				  strChineseCurrency = "负" + strChineseCurrency;
		  }
		  catch (Exception e)
		  {
			  System.out.println("Exception Reason : Call Method doConvert Error");
			  System.out.println("Exception Message : " + e.getMessage());
			  e.printStackTrace();
			  return "";
		  }
			
			  return strChineseCurrency;
	  }	
	  
	  
	public static double round(double v,int bits)
		{
			String format = "####.";
			for(int i=0;i<bits;i++)
			{
				format += "#";
			}
			String s = Value.view(v,format);
		
			return Double.parseDouble(s);
		}
}
